import wx
import wx.lib.agw.hypertreelist as HTL
import wx.lib.agw.genericmessagedialog as GMD

import sqlite3
import math
import numpy

import STATISTIC_GUI

app_path = "D:\\Eigene Datein\\Python\\TIGS DB\\"
source_path = app_path + "files\\"
image_path = app_path + "images\\"

class ControlFrame(wx.Frame):
    """Frame for Hypertree."""
    def __init__(self, tigs_data, request_id):
        wx.Frame.__init__(self, None, title="Shot Validation", size=(800,730))

        self.tree = HyperTreeList(self, data = tigs_data, request_id=request_id)
        self.tree.SetFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))
        self.tree.ExpandAll()
        self.make_menue()

    def make_menue(self):
        # Toolbar
        toolBar = self.CreateToolBar()
        toolBar.AddLabelTool(10, '',
                             wx.Bitmap(image_path + 'ok.png'), shortHelp="Export Sequences")

        # Events
        self.Bind(wx.EVT_TOOL, self.tree.check, id=10)

        toolBar.Realize()

class HyperTreeList(HTL.HyperTreeList):
    """HypertreeList for shot validation."""
    def __init__(self, parent, data, request_id, id=wx.ID_ANY, pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 style=wx.SUNKEN_BORDER,
                 agwStyle=wx.TR_HAS_BUTTONS | wx.TR_HAS_VARIABLE_ROW_HEIGHT|wx.TR_COLUMN_LINES|wx.TR_ROW_LINES|wx.TR_MULTIPLE):

        HTL.HyperTreeList.__init__(self, parent, id, pos, size, style, agwStyle)


        self.AddColumn("Experiment")
        self.AddColumn("Gus cells")
        self.AddColumn("Haustoria")
        self.AddColumn("SI")
        self.AddColumn("Warnings")
        self.SetMainColumn(0) # the one with the tree in it...
        self.SetColumnWidth(0, 210)
        self.SetColumnWidth(4, 175)
        self.SetColumnFont(0, wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))
        self.SetColumnFont(1, wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))
        self.SetColumnFont(2, wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))
        self.SetColumnFont(3, wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))
        self.SetColumnFont(4, wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL))

        self.root = self.AddRoot("Please verify the shots:")

        FILENAME = source_path + "tigs_db_08082011.sdb3"
        conn = sqlite3.connect(FILENAME)
        cur = conn.cursor()

        controls = {}
        self.experiments = data
        self.request_id = request_id
        for id in self.request_id:
            req_id = id

        # Save row data
        f_row = open(source_path + 'selected_tigs_data', 'w')

        # Get controls of experiments.
        for name in self.experiments:
            child = self.AppendItem(self.root, name)#, ct_type=1)
            cur.execute("""
            SELECT
            tube_id,
            gus_cells,
            haustoria_amount,
            id,
            ta_id
            FROM
            TIGS_Table
            WHERE experiment_name = ?
            AND function = 'Positive Control' OR
            experiment_name = ?
            AND
            function = 'Negative Control' OR
            experiment_name = ?
            AND
            function = 'Vector Control'
            OR experiment_name = ? AND
            ta_id = ?
            ORDER BY experiment_name
            """,(str(name), str(name), str(name), str(name), str(req_id)))

            # Get Data
            rows = cur.fetchall()

            for entry in rows:
                f_row.write(str(entry[3]) + '\t' + str(name) + '\t' + str(entry[0]) + '\t' +
                            str(entry[1]) + '\t' + str(entry[2]) + '\n' )

                child2 = self.AppendItem(child, entry[0]+'_'+str(entry[3]), ct_type=1)
                if int(entry[1]) < 50:
                    self.SetItemTextColour(child2, 'RED')
                    self.SetItemText(child2, 'Low gus cells number', 4)

                elif round(float(entry[2])/float(entry[1]), 2) < 0.05 and entry[0] == 'TA30N':
                    self.SetItemTextColour(child2, 'RED')
                    self.SetItemText(child2, 'Low SI', 4)
                elif round(float(entry[2])/float(entry[1]), 2) < 0.05 and entry[0] == 'TA30R':
                    self.SetItemTextColour(child2, 'RED')
                    self.SetItemText(child2, 'Low SI', 4)
                else:
                    self.CheckItem(child2)

                self.SetItemText(child2, entry[1], 1)
                self.SetItemText(child2, entry[2], 2)
                self.SetItemText(child2, str(round(float(entry[2])/float(entry[1]),2)), 3)
                #print entry[0], entry[1], entry[2], float(entry[2])/float(entry[1])

        f_row.close()
        conn.close()
        self.item_map = {}
        #self.Bind(HTL.EVT_TREE_ITEM_CHECKING, self.is_checked)

    def check(self, evt):
        """Get checked shots and save raw data in a file."""
        checked = []
        id1, cookie1 = self.GetFirstChild(self.root)
        while True:
            try:
                if self.GetItemType(id1) == 1:
                    if id1.IsChecked() == True:
                        checked.append(id1.GetText().rsplit('_', 1)[-1])

            except:
                break
            id2, cookie2 = self.GetFirstChild(id1)
            while True:
                try:
                    if self.GetItemType(id2) == 1:
                        if id2.IsChecked() == True:
                            checked.append(id2.GetText().rsplit('_', 1)[-1])

                except:
                    break
                id2, cookie2 = self.GetNextChild(id1, cookie2)
            id1, cookie1 = self.GetNextChild(self.root, cookie1)

        self.calc_percent(checked)

    def calc_percent(self, checked):
        """Calculate SI and percent per shot."""
        # Si = Haustoria/Gus
        # Percent = SI*100/Mean_TA30SI

        f_row = open(source_path + 'selected_tigs_data', 'r')
        selected_data = f_row.readlines()
        mean_values = []
        mean = int()
        d = {}
        removed_exp = set()
        for name in self.experiments:
            for data in selected_data:
                data = data.strip()
                data = data.split('\t')
                if name == data[1]:
                    if data[0] in checked:
                        if data[2] == 'TA30N' or data[2] == 'TA30R':
                            mean_val = float(data[4])/float(data[3])
                            mean_values.append(mean_val)
                        elif data[2] == 'TA30R':
                            mean_val = float(data[4])/float(data[3])
                            mean_values.append(mean_val)


            mean = numpy.average(mean_values)

            for data in selected_data:
                data = data.strip()
                data = data.split('\t')
                if name == data[1]:
                    if data[0] in checked:
                        if data[2] != 'TA30N':
                            percent = (float(data[4])/float(data[3]) * 100) / float(mean)
                            x = float(percent)
                            if not math.isnan(x):
                                d.setdefault(data[2],[]).append((name, percent))
                            else:
                                removed_exp.add(name)
                        elif data[2] != 'TA30R':
                            percent = (float(data[4])/float(data[3]) * 100) / float(mean)
                            x = float(percent)
                            if not math.isnan(x):
                                d.setdefault(data[2],[]).append((name, percent))
                            else:
                                removed_exp.add(name)

            mean_values = []

        if removed_exp != set([]):
            msg = "One or more of your experiments needed to be removed because there where no usable controls:\n"
            for rem in removed_exp:
                msg = msg + rem + '\n'
            dlg = GMD.GenericMessageDialog(self, msg,
                       "Experiment Removed",
                       wx.OK|wx.ICON_ERROR)
            dlg.ShowModal()
            dlg.Destroy()


        self.save_data_for_statistic(d)

    def save_data_for_statistic(self, data):
        """Save final data in proper format for the statistic tool."""

        STRING_WHEN_MISSING = ''

        columns = []
        s = set()
        for i in data.iteritems():
            for x in i[1]:
                s.add(x[0])

        for id in s:
            columns.append(id)
        columns.sort()
        columns.insert(0, 'id')
        exp = set()
        remove =  False
        remove_lst = []
        f = open(source_path + 'statistic_data.txt', 'w')
        for (rowId, rowValues) in sorted(data.items(), key= lambda x: x[0].lower()):
            if rowId == 'TA30N' and len(rowValues) < 4:
                    remove = True
                    remove_lst.append(rowId)
            elif rowId == 'TA30R' and len(rowValues) < 4:
                remove = True
                remove_lst.append(rowId)
            else:
                if len(rowValues) > 1:
                    rowValuesDict = dict(rowValues)
                    rowValuesDict["id"] = rowId

                    for col in columns:
                        exp.add(col)
                        #print str(rowValuesDict.get(col, STRING_WHEN_MISSING))
                        f.write(str(rowValuesDict.get(col, STRING_WHEN_MISSING)) + '\t')
                    f.write('\n')
                else:
                    remove = True
                    remove_lst.append(rowId)

        f.close()

        if remove == True:
            msg = "One or more of your data needed to be removed because there was only one value existing:\n"
            for rem in remove_lst:
                msg = msg + rem + '\n'
            dlg = GMD.GenericMessageDialog(self, msg,
                       "Data Removed",
                       wx.OK|wx.ICON_ERROR)
            dlg.ShowModal()
            dlg.Destroy()
        frame = STATISTIC_GUI.MyFrame(None, -1, 'sTAtistic.py')
        frame.Show()



#    def is_checked(self, evt):
#        self.list = []
#        item = self.GetSelection()
#        exp = self.GetItemParent(item).GetText()
#        shot = item
#        if (exp, shot) not in self.list:
#            self.list.append((exp, shot))
#        #print i.GetText()
#        print self.list
##        item = evt.GetItem()
##        print self.IsItemChecked(item)
##        print item.GetCurrentCheckedImage()
##        print item.GetText()
##        print self.GetItemParent(item).GetText()




#app = wx.PySimpleApp(None)
#frame = TestFrame()
#frame.Show()
#app.MainLoop()